/**
 * @file quality_descriptors.h
 * @brief 品质描述符处理头文件
 * @details 本文件声明了104协议中各种品质描述符的解析和构建功能，
 *          包括SIQ、DIQ、QDS、DCO等品质描述符的处理函数。
 * 
 * @author zyb
 * @date 2025-10-01
 * @version 1.0
 * 
 * @note 品质描述符的位定义严格按照IEC 60870-5-104协议规范
 * @warning 位域结构在不同编译器下可能有不同的内存布局
 * 
 * @see protocol_types.h
 * @see constants.h
 * @see error_codes.h
 */

#ifndef QUALITY_DESCRIPTORS_H
#define QUALITY_DESCRIPTORS_H

#ifdef __cplusplus
extern "C" {
#endif

#include "protocol_types.h"
#include "../../error/include/error_codes.h"

/* ==================== SIQ处理函数声明 ==================== */

/**
 * @brief 解析SIQ品质描述符
 * @details 从字节流中解析SIQ品质描述符，按照协议规范解析各个位域
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param offset 偏移量
 * @param siq SIQ结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 * 
 * @note SIQ位定义：Bit 1=SPI, Bit 4-2=RES, Bit 5=BL, Bit 6=SB, Bit 7=NT, Bit 8=IV
 * @warning 解析后的位域值需要验证有效性
 * 
 * @see siq_t
 * @see validate_siq
 */
protocol_error_t parse_siq(const uint8_t* buffer, size_t buffer_size, size_t offset, siq_t* siq);

/**
 * @brief 构建SIQ品质描述符
 * @details 将SIQ结构转换为字节流，按照协议规范构建各个位域
 * 
 * @param siq SIQ结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param offset 偏移量
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 构建成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 构建前建议先验证SIQ结构的有效性
 * @warning 输出缓冲区必须有足够的空间
 * 
 * @see siq_t
 * @see validate_siq
 */
protocol_error_t build_siq(const siq_t* siq, uint8_t* buffer, size_t offset);

/* ==================== DIQ处理函数声明 ==================== */

/**
 * @brief 解析DIQ品质描述符
 * @details 从字节流中解析DIQ品质描述符，按照协议规范解析各个位域
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param offset 偏移量
 * @param diq DIQ结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 * 
 * @note DIQ位定义：Bit 2-1=DPI, Bit 4-3=RES, Bit 5=BL, Bit 6=SB, Bit 7=NT, Bit 8=IV
 * @warning 解析后的位域值需要验证有效性
 * 
 * @see diq_t
 * @see validate_diq
 */
protocol_error_t parse_diq(const uint8_t* buffer, size_t buffer_size, size_t offset, diq_t* diq);

/**
 * @brief 构建DIQ品质描述符
 * @details 将DIQ结构转换为字节流，按照协议规范构建各个位域
 * 
 * @param diq DIQ结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param offset 偏移量
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 构建成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 构建前建议先验证DIQ结构的有效性
 * @warning 输出缓冲区必须有足够的空间
 * 
 * @see diq_t
 * @see validate_diq
 */
protocol_error_t build_diq(const diq_t* diq, uint8_t* buffer, size_t offset);

/* ==================== QDS处理函数声明 ==================== */

/**
 * @brief 解析QDS品质描述符
 * @details 从字节流中解析QDS品质描述符，按照协议规范解析各个位域
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param offset 偏移量
 * @param qds QDS结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 * 
 * @note QDS位定义：Bit 1=OV, Bit 4-2=RES, Bit 5=BL, Bit 6=SB, Bit 7=NT, Bit 8=IV
 * @warning 解析后的位域值需要验证有效性
 * 
 * @see qds_t
 * @see validate_qds
 */
protocol_error_t parse_qds(const uint8_t* buffer, size_t buffer_size, size_t offset, qds_t* qds);

/**
 * @brief 构建QDS品质描述符
 * @details 将QDS结构转换为字节流，按照协议规范构建各个位域
 * 
 * @param qds QDS结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param offset 偏移量
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 构建成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 构建前建议先验证QDS结构的有效性
 * @warning 输出缓冲区必须有足够的空间
 * 
 * @see qds_t
 * @see validate_qds
 */
protocol_error_t build_qds(const qds_t* qds, uint8_t* buffer, size_t offset);

/* ==================== DCO处理函数声明 ==================== */

/**
 * @brief 解析DCO双点遥控信息元素
 * @details 从字节流中解析DCO双点遥控信息元素，按照协议规范解析各个位域
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param offset 偏移量
 * @param dco DCO结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 * 
 * @note DCO位定义：Bit 2-1=DCS, Bit 7-3=QU, Bit 8=S/E
 * @warning 解析后的位域值需要验证有效性
 * 
 * @see dco_t
 * @see validate_dco
 */
protocol_error_t parse_dco(const uint8_t* buffer, size_t buffer_size, size_t offset, dco_t* dco);

/**
 * @brief 构建DCO双点遥控信息元素
 * @details 将DCO结构转换为字节流，按照协议规范构建各个位域
 * 
 * @param dco DCO结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param offset 偏移量
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 构建成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 构建前建议先验证DCO结构的有效性
 * @warning 输出缓冲区必须有足够的空间
 * 
 * @see dco_t
 * @see validate_dco
 */
protocol_error_t build_dco(const dco_t* dco, uint8_t* buffer, size_t offset);

/* ==================== 品质描述符验证函数声明 ==================== */

/**
 * @brief 验证SIQ品质描述符
 * @details 验证SIQ品质描述符的各个位域是否有效
 * 
 * @param siq SIQ结构，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括保留位检查和位域值范围检查
 * @warning 保留位不为0时会记录警告但不返回错误
 * 
 * @see siq_t
 */
protocol_error_t validate_siq(const siq_t* siq);

/**
 * @brief 验证DIQ品质描述符
 * @details 验证DIQ品质描述符的各个位域是否有效
 * 
 * @param diq DIQ结构，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括DPI值范围检查(0-3)和位域值范围检查
 * @warning 保留位不为0时会记录警告但不返回错误
 * 
 * @see diq_t
 */
protocol_error_t validate_diq(const diq_t* diq);

/**
 * @brief 验证QDS品质描述符
 * @details 验证QDS品质描述符的各个位域是否有效
 * 
 * @param qds QDS结构，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括保留位检查和位域值范围检查
 * @warning 保留位不为0时会记录警告但不返回错误
 * 
 * @see qds_t
 */
protocol_error_t validate_qds_descriptor(const qds_t* qds);

/**
 * @brief 验证DCO双点遥控信息元素
 * @details 验证DCO双点遥控信息元素的各个位域是否有效
 * 
 * @param dco DCO结构，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括DCS值范围检查(0-3)、QU值范围检查(0-31)和S/E位域值范围检查
 * @warning 所有位域值都必须符合协议规范
 * 
 * @see dco_t
 */
protocol_error_t validate_dco(const dco_t* dco);

#ifdef __cplusplus
}
#endif

#endif /* QUALITY_DESCRIPTORS_H */
